<?php
/**
 * User.php
 * phpstorm_company_name_str - phpstorm_company_product_name
 * ***************************************************************************************************************************
 * 版权声明: Copyright ©2019 phpstorm_company_name_str All rights reserved
 * 官方网站: phpstorm_company_product_url
 * 许可声明: 这不是一个自由软件！您只能在购买源代码后或者经 phpstorm_company_name_str 官方授权的前提下对程序代码进行修改和使用，
 * 任何企业或个人都不得在源代码上以任何形式任何目的的再次发布和销售以及镜像或复制,包括但不限于已购买源代码和官方授权者。
 * 警 告  : 如若您或贵司未经正式购买渠道获得授权，请立即停止侵权行为，我们已经委派 phpstorm_company_auth_legal 作为我们侵权
 * 起诉的法律代表，还请您或贵司尊重商业版权以及劳动成果，自觉停止侵权行为。您也可匿名举报侵权行为，一旦您的举报被证实，我们
 * 将会以本版本零售价的 phpstorm_company_product_percent_money% 现金给您，以便作为您的辛苦奖励。同时，我们也将竭尽全力保证您的隐私安全。举报邮箱: phpstorm_company_product_report_mail
 * 协议约定: 本产品遵守 << phpstorm_company_product_protocol >> 的约束,您或贵司也可以访问 phpstorm_company_product_protocol 了解更多详情信息。
 * 致 谢  : 感谢您或贵司对我们产品的支持和热爱，我们将不定期对本产品进行更新和修复bug。还请您和贵司多多指导。更多问题资讯请访问
 * phpstorm_company_product_help_url ,如果您正在对此版本进行二次开发，提bug或者需求可以发送到@author邮箱,或者提交工单。
 * 工单地址是: phpstorm_company_product_ticket_url 我们将尽快为您提出合理的解决方案。
 * 其 他  : 您或贵司也可以登录 phpstorm_company_product_doc_url 查看相关的文档资料以及FAQ！
 * ***************************************************************************************************************************
 * @product ctmoncms
 * @desc
 * @author justary <justary@126.com>
 * @date 2024/06/24 12:51
 * @version phpstorm_company_product_version
 * @copyright phpstorm_company_product_copyright
 */

/**
 * @package app\v1\controller
 *
 * @filesource User.php
 * @author justary <justary@126.com>
 * @date 2024/06/24 12:51
 * @link phpstorm_product_licence
 * @version phpstorm_company_product_version
 * @copyright phpstorm_company_product_copyright
 */


namespace app\v1\controller;


use app\data\components\Oss;
use app\data\logic\PageLogic;
use app\v1\BaseController;
use OSS\Core\OssException;
use OSS\Model\ObjectListInfo;
use OSS\OssClient;
use think\App;
use think\Exception;
use think\facade\Config;
use think\facade\Env;
use think\facade\Lang;
use think\facade\Log;
use think\Request;

/**
 * @OA\Tag(
 *   name="user",
 *   description="用户管理"
 * )
 */
class File extends BaseController
{
    protected $config = [
        // 上传图片配置项
        "imageActionName" => "image",
        "imageFieldName" => "file",
        "imageMaxSize" => 1024 * 1024 * 10,
        "imageAllowFiles" => ['.jpg', '.png', '.jpeg'],
        "imageCompressEnable" => true,
        "imageCompressBorder" => 5000,
        "imageInsertAlign" => "none",
        "imageUrlPrefix" => "",

        // 涂鸦图片上传配置项
        "scrawlActionName" => "crawl",
        "scrawlFieldName" => "file",
        "scrawlMaxSize" => 1024 * 1024 * 10,
        "scrawlUrlPrefix" => "",
        "scrawlInsertAlign" => "none",

        // 截图工具上传
        "snapscreenActionName" => "snap",
        "snapscreenUrlPrefix" => "",
        "snapscreenInsertAlign" => "none",

        // 抓取
        "catcherLocalDomain" => [
            "127.0.0.1",
            "localhost",
        ],
        "catcherActionName" => "catch",
        "catcherFieldName" => "source",
        "catcherUrlPrefix" => "",
        "catcherMaxSize" => 1024 * 1024 * 10,
        "catcherAllowFiles" => ['.jpg', '.png', '.jpeg'],

        // 上传视频配置
        "videoActionName" => "video",
        "videoFieldName" => "file",
        "videoUrlPrefix" => "",
        "videoMaxSize" => 1024 * 1024 * 100,
        "videoAllowFiles" => ['.mp4'],

        // 上传音频配置
        "audioActionName" => "audio",
        "audioFieldName" => "file",
        "audioUrlPrefix" => "",
        "audioMaxSize" => 1024 * 1024 * 100,
        "audioAllowFiles" => ['.mp3'],

        // 上传文件配置
        "fileActionName" => "file",
        "fileFieldName" => "file",
        "fileUrlPrefix" => "",
        "fileMaxSize" => 1024 * 1024 * 100,
        "fileAllowFiles" => ['.zip', '.pdf', '.doc'],

        // 列出图片
        "imageManagerActionName" => "listImage",
        "imageManagerListSize" => 20,
        "imageManagerUrlPrefix" => "",
        "imageManagerInsertAlign" => "none",
        "imageManagerAllowFiles" => ['.jpg', '.png', '.jpeg'],

        // 列出指定目录下的文件
        "fileManagerActionName" => "listFile",
        "fileManagerUrlPrefix" => "",
        "fileManagerListSize" => 20,
        "fileManagerAllowFiles" => ['.zip', '.pdf', '.doc'],

    ];
    protected PageLogic $logic;


    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->logic = new PageLogic();
    }

    public function index()
    {

    }

    public function create()
    {

        $websiteDir = $this->app->getRootPath() . 'public' . DIRECTORY_SEPARATOR . 'wwwroot';
        if (!is_dir($websiteDir)) {
            return $this->respMsg(\config('code.FAILURE'), Lang::get('FAILURE'));
        }

        $oss = $this->logic->getConfigDetailByCode('oss')['data'];

        try {
            $id = $oss['ACCESS_KEY_ID'];
            $secret = $oss['ACCESS_KEY_SECRET'];
            $endpoint = $oss['ENDPOINT'];
            $bucket = $oss['BUCKET'];
            $ossClient = new OssClient($id, $secret, $endpoint);

            // 递归发布前移除page
            $this->removeOssFolder(new Oss($id, $secret, $endpoint), $bucket);
            // 递归发布
            $this->uploadToOSS($websiteDir, $ossClient, $bucket);
            return $this->respMsg(\config('code.SUCCESS'), Lang::get('SUCCESS'));
        } catch (\Exception $e) {
            return $this->respMsg(\config('code.FAILURE'), $e->getMessage());
        }
    }

    public function save(Request $request)
    {
        // 获取表单上传文件
        $files = request()->file('files');
        // 获取配置文件的oss配置
        $ossConfig = $this->logic->getConfigDetailByCode('oss')['data'];

        try {
            $savename = [];
            foreach ($files as $file) {
                $fileName = $file->getOriginalName();
                $extension_file = pathinfo($fileName, PATHINFO_EXTENSION);
                $extension = match (strtolower($extension_file)) {
                    'gif', 'png', 'jpg', 'jpeg' => 'images',
                    'mp4' => 'video',
                    'mp3' => 'audio',
                    default => 'other',
                };
                $fileSize = $file->getSize();
                // 设置支持的文件类型
                $allowedExtensions = ['jpg', 'jpeg', 'gif'];
                // 检查文件类型是否有效
                    $savename[] = \think\facade\Filesystem::disk('public')->putFile($extension, $file);

            }
            $ok = array($savename);


            $responseData = [
                'files' => $savename,
                'count' => $ok,
                'local_url' => DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR,
            ];

            // 添加图片集合
            $this->logic->createNewPhotos([
                "title" => $responseData['files'][0],
                "fu_title" => $responseData['files'][0],
                "photo" => $responseData['local_url'] . $responseData['files'][0],
            ]);

            return $this->respMsg(Config::get('code.SUCCESS'), Lang::get('SUCCESS'), $responseData);
        } catch (\think\exception\ValidateException $e) {
            return $this->respMsg(Config::get('code.Fail'), Lang::get('SUCCESS'), $e->getMessage());
        }
    }

    public function read($id)
    {

    }

    public function edit($id)
    {
        //
        echo 'edit';
    }

    public function update(Request $request, $id)
    {
        //
        echo 'update';
    }

    public function delete($id)
    {
        return $this->respMsg(\config('code.SUCCESS'), \lang('SUCCESS'));
    }

    /**
     * 上传文件到oss
     * @param $ossClient
     * @param $bucketName
     * @return void
     */
    function uploadToOSS($localPath, $ossClient, $bucketName, $ossPath = "")
    {
        if (is_file($localPath)) {
            $fileContent = file_get_contents($localPath);
            $ossKey = $ossPath . basename($localPath);
            try {
                $noRootOssKey = str_replace("wwwroot/", '', $ossKey);
                $ossClient->putObject($bucketName, $noRootOssKey, $fileContent);
            } catch (OssException $e) {
                throw $e;
            }
        } elseif (is_dir($localPath)) {
            $ossFolder = $ossPath . basename($localPath) . '/';
            try {
                if (basename($localPath) != 'wwwroot') {
                    $noRootOssFolder = str_replace("wwwroot/", '', $ossFolder);
                    $ossClient->createObjectDir($bucketName, $noRootOssFolder);
                }
            } catch (OssException $e) {
                throw $e;
            }
            $dir = opendir($localPath);
            while (($file = readdir($dir)) !== false) {
                if ($file != '.' && $file != '..') {
                    $newLocalPath = $localPath . '/' . $file;
                    $newOssPath = $ossFolder;
                    $this->uploadToOSS($newLocalPath, $ossClient, $bucketName, $newOssPath);
                }
            }
            closedir($dir);
        }
    }

    /**
     * 移除oss文件夹
     * @return void
     */
    private function removeOssFolder(Oss $oss, string $bucket): void
    {
        $canNotDel = ['storage', 'uploads'];
        try {
            $objListInfo = $oss->listByObjects($bucket, '');
            $dirs = $objListInfo->getObjectList();
            $files = [];
            for ($i = 0; $i < count($dirs); $i++) {
                $objectKey = $dirs[$i]->getKey();
                if (!in_array(substr($objectKey, 0, strlen($canNotDel[0])), $canNotDel)) {
                    $files[] = $dirs[$i]->getKey();
                }
            }
            $ret = $oss->deleteByObjects($bucket, $files);
            return;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return;
        }
    }
}
